home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1997 December
/
MACPOWER-1997-12.ISO.7z
/
MACPOWER-1997-12.ISO
/
AMUG
/
PROGRAMMING
/
Raven 1.2.sit
/
Raven 1.2
/
Source
/
Foundation
/
OS
/
ZOSQueue.h
< prev
next >
Wrap
Text File
|
1997-02-01
|
4KB
|
149 lines
/*
* File: ZOSQueue.h
* Summary: Wrappers for interrupt safe OS queues.
* Written by: Jesse Jones
*
* Usage: A TOSQueue can be used whenever you need to use something like an STL
* list at interrupt time. The template type you can use with TOSQueue
* is restricted to types that can be implicitly converted to a QElem*.
* Typically this is done by mixing MOSElement into the object you want
* to place in the queue. For example, TSoundCommand maintains an interrupt
* safe list of commands that have been executed:
*
* class TSoundCommand : public MOSElement {
* ...
* };
*
* typedef TOSQueue<TSoundCommand*> ZSoundQueue;
* static ZSoundQueue sCompletedCommands;
*
* At this point you can use a subset of the STL list API to operate on
* the queue.
*
* Copyright ゥ 1996 Jesse Jones.
* For conditions of distribution and use, see copyright notice in ZTypes.h
*
* Change History (most recent first):
*
* <-> 11/10/96 JDJ Created
*/
#pragma once
#include <Iterator.h>
#include <OSUtils.h>
#include <ZDebug.h>
#pragma profile off
// ===================================================================================
// class MOSElement
// A mixin that allows object pointers to be placed in an OS Queue. Derived classes
// *must* inherit from MOSElement first to ensure QElem is placed first in the object.
// ===================================================================================
class MOSElement : public QElem {
//-----------------------------------
// Initialization/Destruction
//
public:
virtual ~MOSElement() {}
MOSElement() {qLink = nil; qType = 0;}
private:
MOSElement(const MOSElement& rhs);
MOSElement& operator=(const MOSElement& rhs);
};
// ===================================================================================
// class TOSQueue
// T should be a pointer to a subclass of QElem (eg something descending from MOSElement).
// ===================================================================================
template <class T>
class TOSQueue : public QHdr {
//-----------------------------------
// Types
//
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference; // const pointer, not const data
typedef size_t size_type;
typedef ptrdiff_t difference_type;
//-----------------------------------
// Initialization/Destruction
//
public:
~TOSQueue() {SAFE_ASSERT(qHead == nil); SAFE_ASSERT(qTail == nil);}
TOSQueue() {qFlags = 0; qHead = qTail = nil;}
private:
TOSQueue(const TOSQueue& rhs);
TOSQueue& operator=(const TOSQueue& rhs);
//-----------------------------------
// Iterator
//
public:
class const_iterator : public bidirectional_iterator<T, difference_type> {
public:
const_iterator(QElem* element = nil) {mElement = (T) element;}
bool operator==(const const_iterator& rhs) const {return mElement == rhs.mElement;}
const_reference operator*() const {return mElement;}
const_iterator& operator++() {if (mElement != nil) mElement = (T) mElement->qLink; return *this;}
const_iterator operator++(int) {const_iterator temp = *this; ++*this; return temp;}
private:
T mElement;
};
//-----------------------------------
// API
//
public:
const_iterator begin() const {return qHead;}
const_iterator end() const {return nil;}
bool empty() const {return qHead == nil;}
const_reference front() const {return (T&) qHead;}
const_reference back() const {return (T&) qTail;}
void push_back(T x) {Enqueue(x, this);}
OSErr erase(const_iterator position) {return Dequeue(*position, this);}
OSErr pop_front() {return Dequeue(qHead, this);}
OSErr pop_back() {return Dequeue(qTail, this);}
OSErr remove(T x) {return Dequeue(x, this);}
OSErr splice(TOSQueue& x);
};
template <class T>
OSErr TOSQueue<T>::splice(TOSQueue& x)
{
OSErr err = noErr;
while (err == noErr && !x.empty()) {
value_type elem = x.front();
err = x.pop_front();
if (err == noErr)
this->push_back(elem);
}
return err;
}
#pragma profile reset